<!--
 The MIT License

 Copyright (c) 2017,2018,2019,2020,2021,2022 Klaus Landsdorf (http://node-red.plus/)
 All rights reserved.
 node-red-contrib-bacnet
-->

<script type="text/javascript">
  RED.nodes.registerType('BACnet-Write', {
    category: 'BACnet',
    color: "#16BAC4",
    defaults: {
      name: {value: ''},
      objectType: {value: '', required:true, validate: RED.validators.number()},
      instance: {type: "BACnet-Instance", required:true},
      valueTag: {value: '', required:true, validate: RED.validators.number()},
      valueValue: {value: ''},
      propertyId: {value: '', required:true, validate: RED.validators.number()},
      priority: {value: ''},
      device: {type: "BACnet-Device", required:true},
      server: {type: "BACnet-Client", required:true},
      multipleWrite: {value: false}
    },
    inputs: 1,
    outputs: 1,
    align: "right",
    icon: "bacnet-icon.png",
    label: function () {
      return this.name || "BACnet Write";
    },
    labelStyle: function () {
      return this.name ? "node_label_italic" : "";
    },
    oneditprepare: function () {
      let node = this
      let multipleWriteCheckbox = $("#node-input-multipleWrite")

      let propertyRow = $("#priority-row")

      multipleWriteCheckbox.change(function () {
        if ($(this).is(":checked")) {
          propertyRow.hide();
        } else {
          propertyRow.show();
        }
      });

      let objectTypeLookupField = $("#node-lookup-objectType")
      let objectTypeField = $("#node-input-objectType")

      objectTypeLookupField.click(function () {
        objectTypeLookupField.addClass('disabled')
        $.getJSON('/bacnet/ObjectTypes', function (data) {
          objectTypeLookupField.removeClass('disabled')
          node.lookupItems = []

          $.each(data, function (i, entry) {
            node.lookupItems.push({value: entry.typeValue, label: entry.label})
          })

          objectTypeField.autocomplete({
            source: node.lookupItems,
            minLength: 0,
            focus: function (event, ui) {
              objectTypeField.val(ui.item.value);
              return false;
            },
            select: function (event, ui) {
              objectTypeField.val(ui.item.value)
              return false;
            },
            close: function (event, ui) {
              objectTypeField.autocomplete("destroy")
            }
          }).autocomplete("search", "")
        })
      })

      let datatypeLookupField = $("#node-lookup-propertyId")
      let datatypeField = $("#node-input-propertyId")

      datatypeLookupField.click(function () {
        datatypeLookupField.addClass('disabled')
        $.getJSON('/bacnet/PropertyIds', function (data) {
          datatypeLookupField.removeClass('disabled')
          node.lookupItems = []

          $.each(data, function (i, entry) {
            node.lookupItems.push({value: entry.typeValue, label: entry.label})
          })

          datatypeField.autocomplete({
            source: node.lookupItems,
            minLength: 0,
            focus: function (event, ui) {
              datatypeField.val(ui.item.value);
              return false;
            },
            select: function (event, ui) {
              datatypeField.val(ui.item.value)
              return false;
            },
            close: function (event, ui) {
              datatypeField.autocomplete("destroy")
            }
          }).autocomplete("search", "")
        })
      })

      let tagTypeLookupField = $("#node-lookup-valueTag")
      let tagTypeField = $("#node-input-valueTag")

      tagTypeLookupField.click(function () {
        tagTypeLookupField.addClass('disabled')
        $.getJSON('/bacnet/ApplicationTags', function (data) {
          tagTypeLookupField.removeClass('disabled')
          node.lookupItems = []

          $.each(data, function (i, entry) {
            node.lookupItems.push({value: entry.typeValue, label: entry.label})
          })

          tagTypeField.autocomplete({
            source: node.lookupItems,
            minLength: 0,
            focus: function (event, ui) {
              tagTypeField.val(ui.item.value);
              return false;
            },
            select: function (event, ui) {
              tagTypeField.val(ui.item.value)
              return false;
            },
            close: function (event, ui) {
              tagTypeField.autocomplete("destroy")
            }
          }).autocomplete("search", "")
        })
      })
    }
  });
</script>

<script type="text/x-red" data-template-name="BACnet-Write">
    <div class="form-row">
        <label for="node-input-name"><i class="icon-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
        <input type="text" id="node-input-name" placeholder="">
    </div>
    <div class="form-row">
        <label for="node-input-objectType"><i class="icon-search"></i> <span data-i18n="bacnet-contrib.label.objectType"></span></label>
        <input type="text" id="node-input-objectType" style="width:60%;" placeholder="8">
        <a id="node-lookup-objectType" class="btn"><i id="node-lookup-topic-icon" class="fa fa-search"></i></a>
    </div>
    <div class="form-row">
        <label for="node-input-instance"><i class="icon-globe"></i> <span data-i18n="bacnet-contrib.label.instance"></span></label>
        <input type="text" id="node-input-instance">
    </div>
    <div class="form-row">
        <h4>Value</h4>
        <hr>
    </div>
    <div class="form-row">
        <label for="node-input-valueTag"><i class="icon-search"></i> <span data-i18n="bacnet-contrib.label.valueTag"></span></label>
        <input type="text" id="node-input-valueTag" style="width:60%;" placeholder="9">
        <a id="node-lookup-valueTag" class="btn"><i id="node-lookup-topic-icon" class="fa fa-search"></i></a>
    </div>
    <div class="form-row">
        <label for="node-input-valueValue"><i class="icon-tag"></i> <span data-i18n="bacnet-contrib.label.valueValue"></span></label>
        <input type="text" id="node-input-valueValue" placeholder="">
    </div>
    <div class="form-row">
        <h4>Properties</h4>
        <hr>
    </div>
    <div class="form-row">
        <label for="node-input-propertyId"><i class="icon-search"></i> <span data-i18n="bacnet-contrib.label.propertyId"></span></label>
        <input type="text" id="node-input-propertyId" style="width:60%;" placeholder="85">
        <a id="node-lookup-propertyId" class="btn"><i id="node-lookup-topic-icon" class="fa fa-search"></i></a>
    </div>
    <div class="form-row">
        <label for="node-input-priority"><i class="icon-tag"></i> <span data-i18n="bacnet-contrib.label.priority"></span></label>
        <input type="text" id="node-input-priority" placeholder="16">
    </div>
    <div class="form-row">
        <hr>
        <h4>Device and Interface</h4>
        <hr>
    </div>
    <div class="form-row">
        <label for="node-input-device"><i class="icon-globe"></i> <span data-i18n="bacnet-contrib.label.device"></span></label>
        <input type="text" id="node-input-device">
    </div>
    <div class="form-row">
        <label for="node-input-server"><i class="icon-globe"></i> <span data-i18n="bacnet-contrib.label.server"></span></label>
        <input type="text" id="node-input-server">
    </div>
    <hr>
    <div class="form-row">
        <label style="min-width:160px" for="node-input-multipleWrite"><i class="fa fa-th"></i>
        <span data-i18n="bacnet-contrib.label.multipleWrite"></span></label>
        <input type="checkbox" id="node-input-multipleWrite" style="max-width:30px">
    </div>
</script>

<script type="text/x-red" data-help-name="BACnet-Write">
    <h2>BACnet Write node</h2>

    <h3>BETA</h3>
    <a href="https://fh1ch.github.io/node-bacstack/" target="_blank">API Docs</a>

    <p>The msg object properties are used if they filled up with some, otherwise it uses the node settings</p>

    <h3>Multiple Write</h3>
    <h4>Input</h4>
    <p>msg.payload.deviceIPAddress</p>

    <strong>msg.payload.values</strong>

    <i>Array of objects with properties:</i>
    <p>objectId.type</p>
    <p>objectId.instance</p>

    <p>values</p>
    <i>Array of objects with properties:</i>
    <p>property.id</p>
    <p>property.index</p>

    <p>value</p>
    <i>Array of objects with properties:</i>
    <p>tag</p>
    <p>value</p>

    <p>Example of msg.payload.values:</p>
    <pre>
        let values = [{
          objectId: {
            type: objectType,
            instance: objectInstance
          },
          values: [{
            property: {
              id: propertyId,
              index: index
            },
            value: [{
              tag: valueTag,
              value: valueValue
            }],
            priority: priority
          }]
        }]
    </pre>

    <pre>
    const values = [{
        objectId: {type: 8, instance: 44301},
        values: [{
            property: {id: 28, index: 12},
            value: [{type: 1, value: true}],
            priority: 15
        }]
    }];
    </pre>
    <p>priority</p>

    <strong>msg.payload.options (all optional)</strong>
    <p>msg.payload.options.maxSegments</p>
    <p>msg.payload.options.maxAdpu</p>
    <p>msg.payload.options.invokeId</p>

    <h3>Simple Write</h3>
    <h4>Input</h4>
    <p>msg.payload.deviceIPAddress</p>

    <strong>msg.payload.objectId</strong>
    <p>msg.payload.objectId.type</p>
    <p>msg.payload.objectId.instance</p>

    <p>msg.payload.propertyId</p>

    <strong>msg.payload.values</strong>
    <i>Array of objects with properties:</i>
    <p>tag</p>
    <p>value</p>

    <strong>msg.payload.options (all optional)</strong>
    <p>msg.payload.options.maxSegments</p>
    <p>msg.payload.options.maxAdpu</p>
    <p>msg.payload.options.invokeId</p>
    <p>msg.payload.options.arrayIndex</p>
    <p>msg.payload.options.priority</p>

    <pre>
        objectId: {type: 8, instance: 44301},
        propertyId: 28,
        values: [{
            type: 4,
            value: 100
        }]
    </pre>

    <h3>All Modes</h3>
    <h4>Output</h4>
    <p>msg.payload</p>

</script>
